package com.priox.sigar.infraestructura.persistence.jpa.sigar;

import com.googlecode.ehcache.annotations.Cacheable;
import com.googlecode.genericdao.search.Search;
import com.mm.support.jpa.BaseDAO;
import com.priox.sigar.client.dto.AgrupacionDTO;
import com.priox.sigar.client.dto.CuentaContableDTO;
import com.priox.sigar.client.flt.CuentaContableFlt;
import com.priox.sigar.domain.model.CuentaContable;
import com.priox.sigar.domain.model.CuentaContableRepository;
import com.priox.sigar.server.infrastructure.persistence.util.WhereParams;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;


/**
 * User: aglwkrs
 * Date: 30/11/11
 */
@Repository
public class CuentaContableRepositoryImpl extends BaseDAO<CuentaContable, String> implements CuentaContableRepository {

    private final static Logger logger = LoggerFactory.getLogger(CuentaContableRepositoryImpl.class);

    private NamedParameterJdbcTemplate parameterJdbcTemplate;
    private JdbcTemplate jdbcTemplate;


    @Autowired
    DataSource dataSource;

    @PostConstruct
    public void init() {
        this.parameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public List<CuentaContable> findByIds(List<String> ids) {
        if (ids.isEmpty()) return new ArrayList<CuentaContable>();
        Search s = new Search();
        s.addFilterIn("cuentaContableId", ids);
        return search(s);
    }

    public List<CuentaContableDTO> findNotIds(List<String> ids) {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT tcc.cuenta_contable_id as \"id\", ");
        sql.append("       tcc.codigo as \"codigo\", ");
        sql.append("       tcc.descripcion as \"descripcion\" ");
        sql.append("FROM   tm_cuenta_contable tcc ");
        sql.append("WHERE  1=1 ");
        WhereParams params = new WhereParams();
        sql.append(params.filterIn(" and tcc.codigo not in   (:id ) ", ids, ""));

        logger.debug(params.replaceForDebug(sql.toString()));
        return parameterJdbcTemplate.query(sql.toString(), params.getParams(), new BeanPropertyRowMapper<CuentaContableDTO>(CuentaContableDTO.class));

    }

    public List<CuentaContable> findByNameList(String name) {
        Search s = new Search();
        if (StringUtils.isNotBlank(name)) {
            s.addFilterILike("nombre", name.toUpperCase() + "%");
            s.addSortAsc("nombre");
        }
        s.addSortAsc("nombre");
        return search(s);


    }


    @Cacheable(cacheName = "cuentaContableByCodigo")
    public CuentaContableDTO findByCodigo(String codigo) {
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT tcc.codigo as \"codigo\", ");
        sql.append("       tcc.descripcion as \"descripcion\", ");
        sql.append("       tcc.cuenta_contable_id as \"cuenta_contable_id\", ");
        sql.append("       ta.agrupacion_id as \"agrupacionId\", ");
        sql.append("       ta.codigo as \"agrupacionCodigo\", ");
        sql.append("       ta.nombre as \"agrupacionNombre\" ");
        sql.append("FROM   SGtm_cuenta_contable tcc, ");
        sql.append("       SGTM_AGRUPACION ta ");
        sql.append("WHERE  tcc.agrupacion_id =ta.agrupacion_id ");
        WhereParams params = new WhereParams();
        sql.append(params.filter(" and tcc.codigo  = :codigo", codigo));
        List result = parameterJdbcTemplate.query(sql.toString(), params.getParams(), new BeanPropertyRowMapper<CuentaContableDTO>(CuentaContableDTO.class));

        if (result.isEmpty()) {
            return null;
        }
        return (CuentaContableDTO) result.get(0);
    }

    public List<CuentaContableDTO> findByFilter(AgrupacionDTO filter) {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT tcc.codigo as \"codigo\", ");
        sql.append("       tcc.cuenta_contable_id as \"id\", ");
        sql.append("       tcc.descripcion as \"descripcion\" ");
        sql.append("FROM   SGtm_cuenta_contable tcc, ");
        sql.append("       SGtm_agrupacion ta ");
        sql.append("WHERE  tcc.agrupacion_id =ta.id ");
        WhereParams params = new WhereParams();
        sql.append(params.filter(" and ta.id  = :id", filter.getAgrupacionId()));
        logger.debug(params.replaceForDebug(sql.toString()));
        return parameterJdbcTemplate.query(sql.toString(), params.getParams(), new BeanPropertyRowMapper<CuentaContableDTO>(CuentaContableDTO.class));
    }

    public List<CuentaContableDTO> findByFilter(CuentaContableFlt filter) {
        StringBuffer sql = new StringBuffer();
        sql.append("SELECT tcc.codigo as \"codigo\", ");
        sql.append("       tcc.descripcion as \"descripcion\", ");
        sql.append("       tcc.cuenta_contable_id as \"cuentaContableId\", ");
        sql.append("       ta.agrupacion_id as \"agrupacionId\", ");
        sql.append("       ta.codigo as \"agrupacionCodigo\", ");
        sql.append("       ta.nombre as \"agrupacionNombre\" ");
        sql.append("FROM   SGtm_cuenta_contable tcc, ");
        sql.append("       SGtm_agrupacion ta ");
        sql.append("WHERE  tcc.agrupacion_Id =ta.agrupacion_Id ");
        WhereParams params = new WhereParams();
        sql.append(params.filter(" and tcc.codigo  = :codigo", filter.getCodigo()));
        if(StringUtils.isNotBlank(filter.getDescripcion())){
            sql.append(" and upper(tcc.descripcion)  like '%"+filter.getDescripcion().toUpperCase()+"%'");
        }

        if(filter.getAgrupacionId()!=null && filter.getAgrupacionId()!=0)
            sql.append(params.filter(" and tcc.agrupacion_id   = :agrupacionId", filter.getAgrupacionId()));
        return parameterJdbcTemplate.query(sql.toString(), params.getParams(), new BeanPropertyRowMapper<CuentaContableDTO>(CuentaContableDTO.class));
    }

    public void saveCadena(CuentaContable cadena) {
        this.persist(cadena);
    }

    public CuentaContable findBy(Long code) {
        Search s = new Search();
        if (code != null) {
            s.addFilterEqual("id", code);
        }
        return searchUnique(s);
    }

    public void delete(CuentaContableDTO nuevoRegistro) {
//        jdbcTemplate.update("delete from TM_CUENTA_CONTABLE where codigo = ? ",
//                new Object[]{nuevoRegistro.getCuentaContableId()});
    }

    public List<CuentaContable> findByRUC(String ruc) {
        Search s = new Search();
        if (ruc != null) {
            s.addFilterEqual("ruc", ruc);
        }

        return search(s);
    }


}
